xenu's socket tutorial


Have you ever wondered how some of those scripts make version checkers or how they download the latest version of there script? Those scripts do it by sockets. A socket is a raw connection that allows you to send and receive info. You open a socket on a port. For example, the default port for connecting to an ftp is 21. So to connect to a ftp, you would use -

sockopen 21 (or whatever port)

The alias 'sockopen' opens a socket to the specified address and port. If you don't put a IP, it will resolve the address (if it can't, it will echo). Time for sending data. When you connect to a server, usually you send data first. For example:

on *:sockopen:helloworld:{ 
  sockwrite -n $sockname GET / HTTP/1.1
  sockwrite -n $sockname Host: www.yahoo.com
  sockwrite -n $sockname Connection: Keep-Alive
  sockwrite -n $sockname $crlf
}


The '-n' switch tells the /sockwrite command to add a $crlf at the end. This example, when a socket was opened to yahoo.com on port 80 and the name is 'helloworld', then the on *:sockopen: event would have sent that data. That data would have made the server send the HTML. But, we can't get the HTML just yet. On to the on *:sockread: event and the /sockread alias.

on *:sockread:helloworld:{
  sockread %temp
  echo -a %temp
}


As soon as the 'helloworld' socket started recieving data, it would echo the data to the active window. The sockread alias sends the data to the variable. Then its up to you what do with the data. You could parse out the latest version for example using $gettok Here's an example that I made to get the latest version of mirc.

alias ver sockclose mirc | sockopen mirc mirc.com 80
on *:sockopen:mirc:{ sockwrite -n $sockname GET / HTTP/1.1 sockwrite -n $sockname Host: mirc.com $+ $str($crlf ,2) }
on *:sockread:mirc:{ 
  sockread %temp 
  if (has been released! isin %temp) { echo $color(info) -a Lastest version of mIRC: $matchtok(%temp,v,2,32) } 
}

As you can see, sockets aren't too hard eh? To get the status a socket, you can use $sock. The format for $sock is $sock(,).

Taken from the mIRC help file, here are the properties:

.name is the name you give to a connection to identify it
.sent and .rcvd return the number of bytes sent and rcvd over that connection so far
.sq and .rq return the number of bytes queued in the send and receive buffers respectively
.ls and .lr return the number of seconds since the connection last sent and last received info
.mark is a user storage area max. 512 bytes (see /sockmark)
.type returns the socket type, TCP or UDP
.saddr and .sport return the source address and port of the last received UDP packet
.to returns the number of seconds the socket has been open
.wserr returns the last winsock error number that occurred on a socket
.wsmsg returns the last winsock error message match the error number


$sockname returns the name of the active socket. So if your using wildcards in a socketname and you need to know what socket to write too, you would use $sockname. If you were checking for a $sockerr, which you probably should, you would use if ($sockerr) { blah } or if ($sockerr > 0) { blah }. Other misc commands include /sockrename , which you can use to rename a socket (I don't know why you would want to do that though). And /sockclose, which you can use to close a socket before its all done recieving data.

There's also an "on:sockclose:" event. You could use this in a game for example, to message the nick if the connection was dropped for some reason.

Now for the socklisten stuff. /socklisten makes the named socket listen on the port (obviously). With this you can listen on ports for anything. Theres the "on:socklisten:" event, so you can accept the socket if you choose. You accept the socket by doing /sockaccept . Then you can send data and recieve data to the named socket. I won't get into UDP sockets, as I have never seen any script that used them. If you want me to add them, email me I guess.

And thats the end of the tutorial. Use the comments form for any questions. Thanks for reading! :D

- xenu

Thanks to webprofit and Dark0ne for comments and suggestions.